// $Id$
/*
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#define TIMER_REFRESH_RATE CLOCKS_PER_SEC*2

#define S_TIMER 1
#define S_STOP 2
#define S_EXIT 3
#define S_STACKMAT 4

	GtkWidget *TimerWindow;
	GtkWidget *TimerLabel;
	
	GTimer *tim;

double end;
double lasttime;
gulong buffer;
int status;
int splittime;

char timer_text[] = "<span font_desc=\"48\">00:00:00</span>\0";
char stackmat_pre[] = "Stackmat mode";
char stackmat_post[] = "Stackmat ready";


gboolean _timer_key_press(GtkWidget *a,GdkEventKey *ev)
{
	if(ev->keyval==GDK_Escape)
	{
		gtk_widget_hide(TimerWindow);
		status=S_EXIT;
		return TRUE;
	}
	if(status==S_STACKMAT)
	{
		gtk_label_set_markup(GTK_LABEL(TimerLabel),stackmat_post);
		return TRUE;
	}

	if(!status)
	{
		g_timer_reset(tim);
		g_timer_start(tim);
		gdk_beep();
		status=S_TIMER;
		return TRUE;
	}

	if(status==S_TIMER)
		status=S_STOP;
	return TRUE;
}

gboolean _timer_key_release(GtkWidget *a,GdkEventKey *ev)
{
	if(!status || status==S_STACKMAT) // Preinspection
	{
		g_timer_reset(tim);
		g_timer_start(tim);
		gdk_beep();
		status=S_TIMER;
	}

	return TRUE;

}

void _timer_onhide(GtkWidget *a)
{
	status=S_EXIT;
}

void _fmt_time(double t,char s[9])
{
	s[2]=':';
	s[5]=':';
	int ti=(int)t;
	s[0]=ti/600+'0';
	ti%=600;
	s[1]=ti/60+'0';
	ti%=60;
	
	s[3]=ti/10+'0';
	ti%=10;
	s[4]=ti+'0';
	
	ti=(int)t;
	t-=(double)ti;

	t*=10;
	ti=(int)t;
	s[6]=ti+'0';
	
	ti=(int)t;
	t-=(double)ti;
	
	t*=10;
	ti=(int)t;
	s[7]=ti+'0';

}

gboolean _timer(gpointer a)
{
	if(!status || status==S_STACKMAT) return TRUE;
	double t=g_timer_elapsed(tim,&buffer);
	if(status>S_TIMER)
	{
		g_timer_stop(tim);
		if(status==S_STOP)
		{
			gtk_widget_hide(GTK_WIDGET(TimerWindow));
			lasttime=t;
			//lasttime=g_timer_elapsed(tim,&buffer);
			_run_callback(lasttime);
		}
		gtk_widget_hide(GTK_WIDGET(TimerWindow));
		return FALSE;
	}
	_fmt_time(t,timer_text+21);
	gtk_label_set_markup(GTK_LABEL(TimerLabel),timer_text);
	return TRUE;
}

gboolean _preinspection(gpointer a)
{
	double t=round(g_timer_elapsed(tim,&buffer));
	if(status) return FALSE;
	if(status==S_EXIT)
	{
		g_timer_stop(tim);
		return FALSE;
	}

	int ti=(int)end-(int)t;
	if(ti<=3) 
		gdk_beep();
		//TimerWindow->get_display()->beep();
	{}

	if(t>=end)
	{
		g_timer_reset(tim);
		g_timer_start(tim);
		gdk_beep();
		gdk_beep();
		//TimerWindow->get_display()->beep();
		status=S_TIMER;
		return FALSE;
	}

	t=end-t;
	_fmt_time(t,timer_text+21);
	gtk_label_set_markup(GTK_LABEL(TimerLabel),timer_text);
	
	return TRUE;
}

void init(GtkWidget *parent)
{
	TimerWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
	TimerLabel = gtk_label_new("");
	gtk_label_set_markup(GTK_LABEL(TimerLabel),timer_text);
	gtk_container_add (GTK_CONTAINER (TimerWindow), TimerLabel);
	gtk_widget_show(TimerLabel);
	gtk_window_set_modal(GTK_WINDOW(TimerWindow),TRUE);
	gtk_window_set_decorated(GTK_WINDOW(TimerWindow),FALSE);
	gtk_window_set_transient_for(GTK_WINDOW(TimerWindow),GTK_WINDOW(parent));
	gtk_window_set_position(GTK_WINDOW(TimerWindow),GTK_WIN_POS_CENTER_ALWAYS);
	gtk_window_position(GTK_WINDOW(TimerWindow),GTK_WIN_POS_CENTER_ON_PARENT);
	gtk_container_set_border_width(GTK_CONTAINER(TimerWindow),15);
	tim=g_timer_new();
}



void run(int preinsp)
{
	g_signal_connect(G_OBJECT(TimerWindow),"key_press_event",G_CALLBACK(_timer_key_press),NULL);
	g_signal_connect(G_OBJECT(TimerWindow),"hide",G_CALLBACK(_timer_onhide),NULL);

	//splittime=split;
	status=0;
	gtk_widget_show(GTK_WIDGET(TimerWindow));

	end=preinsp;
	_fmt_time((double)preinsp,timer_text+21);
	gtk_label_set_markup(GTK_LABEL(TimerLabel),timer_text);

	g_timer_reset(tim);
	g_timer_start(tim);
	
	if(preinsp)
		g_timeout_add(1000,_preinspection,NULL);
	else
		status=S_TIMER;
	g_timeout_add(80,_timer,NULL);
}

void run_stackmat()
{
	g_signal_connect(G_OBJECT(TimerWindow),"key_press_event",G_CALLBACK(_timer_key_press),NULL);
	g_signal_connect(G_OBJECT(TimerWindow),"hide",G_CALLBACK(_timer_onhide),NULL);
	g_signal_connect(G_OBJECT(TimerWindow),"key_release_event",G_CALLBACK(_timer_key_release),NULL);

	status=S_STACKMAT;
	gtk_widget_show(GTK_WIDGET(TimerWindow));

	gtk_label_set_markup(GTK_LABEL(TimerLabel),stackmat_pre);
	g_timeout_add(80,_timer,NULL);
}

double getLastTime()
{
		return lasttime;
}



